# dj-stripe in version 2.8.0 dropped support for text-based JSON fields and hasn't provided migration to work it out.
#
# The migration below is based on the discussion by dj-stripe team available under those links:
# - https://github.com/dj-stripe/dj-stripe/issues/1566
# - https://github.com/dj-stripe/dj-stripe/issues/517

from django.core.management.base import BaseCommand
from django.db import transaction, connection

AFFECTED_FIELDS = [
    ("djstripe_account", "business_profile"),
    ("djstripe_account", "company"),
    ("djstripe_account", "individual"),
    ("djstripe_account", "requirements"),
    ("djstripe_account", "settings"),
    ("djstripe_account", "tos_acceptance"),
    ("djstripe_invoice", "customer_address"),
    ("djstripe_invoice", "customer_shipping"),
    ("djstripe_invoice", "discount"),
    ("djstripe_invoice", "status_transitions"),
    ("djstripe_invoice", "threshold_reason"),
    ("djstripe_upcominginvoice", "customer_address"),
    ("djstripe_upcominginvoice", "customer_shipping"),
    ("djstripe_upcominginvoice", "discount"),
    ("djstripe_upcominginvoice", "status_transitions"),
    ("djstripe_upcominginvoice", "threshold_reason"),
    ("djstripe_invoiceitem", "period"),
    ("djstripe_plan", "tiers"),
    ("djstripe_plan", "transform_usage"),
    ("djstripe_subscription", "billing_thresholds"),
    ("djstripe_subscription", "discount"),
    ("djstripe_subscription", "pending_invoice_item_interval"),
    ("djstripe_subscription", "pending_update"),
    ("djstripe_subscriptionitem", "billing_thresholds"),
    ("djstripe_subscriptionschedule", "current_phase"),
    ("djstripe_subscriptionschedule", "default_settings"),
    ("djstripe_subscriptionschedule", "phases"),
    ("djstripe_taxid", "verification"),
    ("djstripe_usagerecordsummary", "period"),
    ("djstripe_session", "display_items"),
    ("djstripe_session", "payment_method_types"),
    ("djstripe_countryspec", "supported_bank_account_currencies"),
    ("djstripe_countryspec", "supported_payment_currencies"),
    ("djstripe_countryspec", "supported_payment_methods"),
    ("djstripe_countryspec", "supported_transfer_countries"),
    ("djstripe_countryspec", "verification_fields"),
    ("djstripe_balancetransaction", "fee_details"),
    ("djstripe_charge", "billing_details"),
    ("djstripe_charge", "fraud_details"),
    ("djstripe_charge", "outcome"),
    ("djstripe_charge", "payment_method_details"),
    ("djstripe_charge", "shipping"),
    ("djstripe_charge", "transfer_data"),
    ("djstripe_mandate", "customer_acceptance"),
    ("djstripe_mandate", "payment_method_details"),
    ("djstripe_mandate", "multi_use"),
    ("djstripe_mandate", "single_use"),
    ("djstripe_product", "attributes"),
    ("djstripe_product", "deactivate_on"),
    ("djstripe_product", "images"),
    ("djstripe_product", "package_dimensions"),
    ("djstripe_customer", "address"),
    ("djstripe_customer", "invoice_settings"),
    ("djstripe_customer", "preferred_locales"),
    ("djstripe_customer", "shipping"),
    ("djstripe_dispute", "balance_transactions"),
    ("djstripe_dispute", "evidence"),
    ("djstripe_dispute", "evidence_details"),
    ("djstripe_event", "data"),
    ("djstripe_paymentintent", "last_payment_error"),
    ("djstripe_paymentintent", "next_action"),
    ("djstripe_paymentintent", "payment_method_types"),
    ("djstripe_paymentintent", "shipping"),
    ("djstripe_paymentintent", "transfer_data"),
    ("djstripe_setupintent", "last_setup_error"),
    ("djstripe_setupintent", "next_action"),
    ("djstripe_setupintent", "payment_method_types"),
    ("djstripe_price", "recurring"),
    ("djstripe_price", "tiers"),
    ("djstripe_price", "transform_quantity"),
    ("djstripe_source", "owner"),
    ("djstripe_source", "code_verification"),
    ("djstripe_source", "receiver"),
    ("djstripe_source", "redirect"),
    ("djstripe_source", "source_data"),
    ("djstripe_paymentmethod", "billing_details"),
    ("djstripe_paymentmethod", "acss_debit"),
    ("djstripe_paymentmethod", "afterpay_clearpay"),
    ("djstripe_paymentmethod", "alipay"),
    ("djstripe_paymentmethod", "au_becs_debit"),
    ("djstripe_paymentmethod", "bacs_debit"),
    ("djstripe_paymentmethod", "bancontact"),
    ("djstripe_paymentmethod", "boleto"),
    ("djstripe_paymentmethod", "card"),
    ("djstripe_paymentmethod", "card_present"),
    ("djstripe_paymentmethod", "eps"),
    ("djstripe_paymentmethod", "fpx"),
    ("djstripe_paymentmethod", "giropay"),
    ("djstripe_paymentmethod", "grabpay"),
    ("djstripe_paymentmethod", "ideal"),
    ("djstripe_paymentmethod", "interac_present"),
    ("djstripe_paymentmethod", "oxxo"),
    ("djstripe_paymentmethod", "p24"),
    ("djstripe_paymentmethod", "sepa_debit"),
    ("djstripe_paymentmethod", "sofort"),
    ("djstripe_paymentmethod", "wechat_pay"),
    ("djstripe_scheduledqueryrun", "error"),
    ("djstripe_webhookendpoint", "enabled_events"),
    ("djstripe_webhookeventtrigger", "headers"),
    ("djstripe_account", "metadata"),
    ("djstripe_coupon", "metadata"),
    ("djstripe_invoice", "metadata"),
    ("djstripe_upcominginvoice", "metadata"),
    ("djstripe_invoiceitem", "metadata"),
    ("djstripe_plan", "metadata"),
    ("djstripe_subscription", "metadata"),
    ("djstripe_subscriptionitem", "metadata"),
    ("djstripe_subscriptionschedule", "metadata"),
    ("djstripe_taxrate", "metadata"),
    ("djstripe_session", "metadata"),
    ("djstripe_applicationfee", "metadata"),
    ("djstripe_applicationfeerefund", "metadata"),
    ("djstripe_transfer", "metadata"),
    ("djstripe_transferreversal", "metadata"),
    ("djstripe_balancetransaction", "metadata"),
    ("djstripe_charge", "metadata"),
    ("djstripe_mandate", "metadata"),
    ("djstripe_product", "metadata"),
    ("djstripe_customer", "metadata"),
    ("djstripe_dispute", "metadata"),
    ("djstripe_event", "metadata"),
    ("djstripe_file", "metadata"),
    ("djstripe_filelink", "metadata"),
    ("djstripe_paymentintent", "metadata"),
    ("djstripe_setupintent", "metadata"),
    ("djstripe_payout", "metadata"),
    ("djstripe_price", "metadata"),
    ("djstripe_refund", "metadata"),
    ("djstripe_bankaccount", "metadata"),
    ("djstripe_card", "metadata"),
    ("djstripe_source", "metadata"),
    ("djstripe_paymentmethod", "metadata"),
    ("djstripe_scheduledqueryrun", "metadata"),
    ("djstripe_webhookendpoint", "metadata"),
]


class Command(BaseCommand):
    help = 'Migrate text-based JSON fields to json-based ones to support dj-stripe v2.8.0'

    @transaction.atomic
    def handle(self, *args, **options):
        with connection.cursor() as cursor:
            for af in AFFECTED_FIELDS:
                self.stdout.write(f'Migrating field "{af[1]}" of "{af[0]}" table..')
                cursor.execute(f'ALTER TABLE {af[0]} ALTER COLUMN "{af[1]}" TYPE jsonb USING "{af[1]}"::text::jsonb;')
            self.stdout.write(self.style.SUCCESS("Migration successful!"))
